home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / xlib / tcilight.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  14KB  |  543 lines

  1. /*
  2.  * (c) Copyright 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. /*
  39. ** Test Color Index Lighting
  40. */
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <math.h>
  45. #include <X11/Xlib.h>
  46. #include <X11/keysym.h>
  47. #include <GL/gl.h>
  48. #include <GL/glx.h>
  49.  
  50. float indexScale = 1.0;
  51.  
  52. int useLighting = 0;
  53. int useTwoSide = 0;
  54. int useLocalLight = 0;
  55. int useLocalViewer = 0;
  56. int useSpot = 0;
  57. int useAtten = 0;
  58. int whichObject = 0;
  59.  
  60. float modelAmb[4] = { 0.0, 0.0, 0.0, 0.0 };
  61.  
  62. float lightPosInf[4] = { 0.0, 0.0, 1.0, 0.0 };
  63. float lightPosLoc[4] = { 0.0, 0.0, 4.0, 1.0 };
  64. float lightAmb[4] = { 0.2, 0.2, 0.2, 0.0 };
  65. float lightDiff[4] = { 0.6, 0.6, 0.6, 0.0 };
  66. float lightSpec[4] = { 0.2, 0.2, 0.2, 0.0 };
  67. float lightSpotDir[3] = { 0.0, 0.0, -1.0 };
  68. float lightSpot[2] = { 100.0, 30.0 };
  69. float lightAtten[3] = { 0.80, 0.25, 0.05 };
  70.  
  71. float matIndexRange[3] = { 0.05, 0.75, 0.95 };
  72. float matIndexes[3] = { 0.0, 0.0, 0.0 };
  73. float matShininess[1] = { 10.0 };
  74.  
  75. static void
  76. init(void)
  77. {
  78.     glClearIndex(0.0);
  79.  
  80.     glMatrixMode(GL_PROJECTION);
  81.     glLoadIdentity();
  82.     glFrustum(-1, 1, -1, 1, 1, 3);
  83.  
  84.     glMatrixMode(GL_MODELVIEW);
  85.     glLoadIdentity();
  86.     glTranslatef(0.0, 0.0, -2.0);
  87.  
  88.     glEnable(GL_DEPTH_TEST);
  89.     glEnable(GL_NORMALIZE);
  90.  
  91.     glLineWidth(2.0);
  92. }
  93.  
  94. static void
  95. reconfig(void)
  96. {
  97.     glLightModelfv(GL_AMBIENT, modelAmb);
  98.     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, useLocalViewer);
  99.     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, useTwoSide);
  100.  
  101.     glLightfv(GL_LIGHT0, GL_POSITION, useLocalLight ? lightPosLoc:lightPosInf);
  102.     glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  103.     glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  104.     glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
  105.     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightSpotDir);
  106.     glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, useSpot ? lightSpot[0]:1.0);
  107.     glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, useSpot ? lightSpot[1]:180.0);
  108.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, useAtten ? lightAtten[0]:1.0);
  109.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, useAtten ? lightAtten[1]:0.0);
  110.     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, useAtten ? lightAtten[2]:0.0);
  111.     glEnable(GL_LIGHT0);
  112.  
  113.     matIndexes[0] = matIndexRange[0]*indexScale;
  114.     matIndexes[1] = matIndexRange[1]*indexScale;
  115.     matIndexes[2] = matIndexRange[2]*indexScale;
  116.     glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, matIndexes);
  117.     glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, matShininess);
  118.  
  119.     if (useLighting) {
  120.     glEnable(GL_LIGHTING);
  121.     } else {
  122.     glDisable(GL_LIGHTING);
  123.     }
  124.  
  125. }
  126.  
  127. static void
  128. drawMaterialMeter(void)
  129. {
  130.     if (useLighting) glDisable(GL_LIGHTING);
  131.  
  132.     glPushMatrix();
  133.     glLoadIdentity();
  134.     glTranslatef(0.7, -0.9, -1.0);
  135.     glScalef(0.2, 1.8, 1.0);
  136.  
  137.     glBegin(GL_LINES);
  138.     glIndexf(0.95*indexScale);
  139.     glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0);
  140.     glVertex2f(1.0, 0.0); glVertex2f(1.0, 1.0);
  141.     glVertex2f(1.0, 1.0); glVertex2f(0.0, 1.0);
  142.     glVertex2f(0.0, 1.0); glVertex2f(0.0, 0.0);
  143.  
  144.     glIndexf(0.25*indexScale);
  145.     glVertex2f(0.0, matIndexRange[0]); glVertex2f(1.0, matIndexRange[0]);
  146.  
  147.     glIndexf(0.50*indexScale);
  148.     glVertex2f(0.0, matIndexRange[1]); glVertex2f(1.0, matIndexRange[1]);
  149.  
  150.     glIndexf(0.75*indexScale);
  151.     glVertex2f(0.0, matIndexRange[2]); glVertex2f(1.0, matIndexRange[2]);
  152.     glEnd();
  153.  
  154.     glPopMatrix();
  155.  
  156.     if (useLighting) glEnable(GL_LIGHTING);
  157. }
  158.  
  159. static void
  160. drawGrid(void)
  161. {
  162.     static int dlist = 0;
  163.  
  164.     if (dlist) {
  165.     glCallList(dlist);
  166.     } else {
  167.     int u = 8, v = 8;
  168.     float du = 1.0 / u;
  169.     float dv = 1.0 / v;
  170.     int i, j;
  171.  
  172.     dlist = glGenLists(1);
  173.     glNewList(dlist, GL_COMPILE_AND_EXECUTE);
  174.  
  175.     glNormal3f(0.0, 0.0, 1.0);
  176.     glBegin(GL_QUADS);
  177.     for (j=0; j<v; ++j) {
  178.         float y = j * dv;
  179.  
  180.         for (i=0; i<u; ++i) {
  181.         float x = i * du;
  182.  
  183.         if ((i ^ j) & 1) {
  184.             glIndexf(0.25*indexScale);
  185.         } else {
  186.             glIndexf(0.75*indexScale);
  187.         }
  188.         glVertex2f(x   , y   );
  189.         glVertex2f(x+du, y   );
  190.         glVertex2f(x+du, y+dv);
  191.         glVertex2f(x   , y+dv);
  192.         }
  193.     }
  194.     glEnd();
  195.  
  196.     glEndList();
  197.     }
  198. }
  199.  
  200. static void
  201. drawCylinder(void)
  202. {
  203.     static int dlist = 0;
  204.  
  205.     if (dlist) {
  206.     glCallList(dlist);
  207.     } else {
  208.     int u = 16;
  209.     float du = (2*M_PI) / u;
  210.     int i, j;
  211.  
  212.     dlist = glGenLists(1);
  213.     glNewList(dlist, GL_COMPILE_AND_EXECUTE);
  214.  
  215.     glBegin(GL_TRIANGLE_STRIP);
  216.     for (i=0; i<=u; ++i) {
  217.         float t = i * du;
  218.         float x = 0.5 * (float)cos((double) t) + 0.5;
  219.         float y = 0.5 * (float)sin((double) t) + 0.5;
  220.  
  221.         glNormal3f(2.0 * (x - 0.5), 2.0 * (y - 0.5), 0.0);
  222.         glIndexf(0.80*indexScale);
  223.         glVertex3f(x, y,  0.5);
  224.         glIndexf(0.20*indexScale);
  225.         glVertex3f(x, y, -0.5);
  226.     }
  227.     glEnd();
  228.  
  229.     glEndList();
  230.     }
  231. }
  232.  
  233. #define NUM_OBJECTS 2
  234. static void (*drawObject[NUM_OBJECTS])(void) = { drawGrid, drawCylinder };
  235.  
  236. static void
  237. redraw(float xrot, float yrot)
  238. {
  239.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  240.  
  241.     drawMaterialMeter();
  242.  
  243.     glPushMatrix();
  244.     glRotatef(xrot, 1, 0, 0);
  245.     glRotatef(yrot, 0, 1, 0);
  246.  
  247.     glPushMatrix();
  248.     glScalef(1.5, 1.5, 1.25);
  249.     glTranslatef(-0.5, -0.5, 0.0);
  250.     (*drawObject[whichObject])();
  251.     glPopMatrix();
  252.  
  253.     glPopMatrix();
  254. }
  255.  
  256. static Colormap
  257. buildGrayScaleColormap(Display *dpy, XVisualInfo *vis)
  258. {
  259.     Colormap cmap;
  260.  
  261.     cmap = XCreateColormap(dpy, RootWindow(dpy, vis->screen),
  262.                vis->visual, AllocNone);
  263.  
  264.     if (vis->class == PseudoColor) {
  265.     int mapSize = 1 << vis->depth;
  266.     int firstEntry = 0;
  267.     int entry;
  268.     unsigned long *pix;
  269.  
  270.     pix = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
  271.  
  272.     if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pix, mapSize)) {
  273.         if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pix, mapSize-1)) {
  274.         fprintf(stderr, "can't alloc enough colormap entries\n");
  275.         exit(EXIT_FAILURE);
  276.         }
  277.         firstEntry = 1;
  278.     }
  279.  
  280.     for (entry=firstEntry; entry<mapSize; ++entry) {
  281.         XColor col;
  282.         int val = entry * (0xffff / (mapSize-1));
  283.  
  284.         col.pixel = entry;
  285.         col.red   = val;
  286.         col.green = val;
  287.         col.blue  = val;
  288.         col.flags = DoRed | DoGreen | DoBlue;
  289.  
  290.         XStoreColor(dpy, cmap, &col);
  291.     }
  292.  
  293.     free((void *) pix);
  294.     } else {
  295.     fprintf(stderr, "can't build colormap for selected visual\n");
  296.     exit(EXIT_FAILURE);
  297.     }
  298.  
  299.     return cmap;
  300. }
  301.  
  302. static Bool
  303. waitForMapNotify(Display *dpy, XEvent *ev, XPointer arg)
  304. {
  305.     return ((ev->type == MapNotify) && (ev->xmapping.window == (Window) arg));
  306. }
  307.  
  308. static int visualAttrs[] = {
  309.     GLX_DOUBLEBUFFER,
  310.     GLX_BUFFER_SIZE, 4,
  311.     GLX_DEPTH_SIZE, 1,
  312.     GLX_LEVEL, 0,
  313.     None,
  314. };
  315.  
  316. int
  317. main(int argc, char **argv)
  318. {
  319.     Display *dpy;
  320.     int scrn;
  321.     Window root;
  322.     XVisualInfo *vis;
  323.     GLXContext ctx;
  324.     Colormap cmap;
  325.     XSizeHints sizehints;
  326.     XSetWindowAttributes swa;
  327.     Window win;
  328.     XEvent ev;
  329.     char *name = "ColorIndex Lighting";
  330.     char *geometry = NULL;
  331.     int x = 0;
  332.     int y = 0;
  333.     unsigned int width = 300;
  334.     unsigned int height = 300;
  335.     int needsReconfig = 1;
  336.     int needsRedraw = 1;
  337.     int done = 0;
  338.     float xrot = 0.0;
  339.     float yrot = 0.0;
  340.     int x0, y0;
  341.     int i;
  342.  
  343.     for (i=1; i<argc; ++i) {
  344.     if ((strcmp("-geometry", argv[i]) == 0) && (i+1 < argc)) {
  345.         geometry = argv[++i];
  346.     }
  347.     }
  348.  
  349.     if ((dpy = XOpenDisplay(NULL)) == NULL) {
  350.     fprintf(stderr, "can't open display\n");
  351.     exit(EXIT_FAILURE);
  352.     }
  353.     scrn = DefaultScreen(dpy);
  354.     root = RootWindow(dpy, scrn);
  355.  
  356.     if ((vis = glXChooseVisual(dpy, scrn, visualAttrs)) == NULL) {
  357.     fprintf(stderr, "can't find visual\n");
  358.     exit(EXIT_FAILURE);
  359.     }
  360.  
  361.     if ((ctx = glXCreateContext(dpy, vis, NULL, True)) == NULL) {
  362.     fprintf(stderr, "can't create context\n");
  363.     exit(EXIT_FAILURE);
  364.     }
  365.  
  366.     sizehints.flags = PPosition | PSize;
  367.     sizehints.width = (int) width;
  368.     sizehints.height = (int) height;
  369.     sizehints.x = x;
  370.     sizehints.y = y;
  371.     if (geometry) {
  372.     int flags = XParseGeometry(geometry, &x, &y, &width, &height);
  373.  
  374.     if (flags & WidthValue) {
  375.        sizehints.flags |= USSize;
  376.        sizehints.width = (int) width;
  377.     }
  378.     if (flags & WidthValue) {
  379.        sizehints.flags |= USSize;
  380.        sizehints.height = (int) height;
  381.     }
  382.     if (flags & XValue) {
  383.        if (flags & XNegative) {
  384.            x = DisplayWidth(dpy, scrn) + x - sizehints.width;
  385.        }
  386.        sizehints.flags |= USPosition;
  387.        sizehints.x = x;
  388.     }
  389.     if (flags & YValue) {
  390.        if (flags & YNegative) {
  391.            y = DisplayHeight(dpy, scrn) + y - sizehints.height;
  392.        }
  393.        sizehints.flags |= USPosition;
  394.        sizehints.y = y;
  395.     }
  396.     }
  397.  
  398.     cmap = buildGrayScaleColormap(dpy, vis);
  399.  
  400.     swa.colormap = cmap;
  401.     swa.background_pixel = None;
  402.     swa.border_pixel = None;
  403.     win = XCreateWindow(dpy, root,
  404.             sizehints.x, sizehints.y,
  405.             sizehints.width, sizehints.height, 0,
  406.             vis->depth, InputOutput, vis->visual,
  407.             CWColormap | CWBackPixel | CWBorderPixel, &swa);
  408.     
  409.     XSetStandardProperties(dpy, win, name, name, None, argv, argc, &sizehints);
  410.     
  411.     XSelectInput(dpy, win,
  412.          StructureNotifyMask | ExposureMask |
  413.          KeyPressMask | ButtonPressMask | ButtonMotionMask);
  414.     
  415.     XMapWindow(dpy, win);
  416.     XIfEvent(dpy, &ev, waitForMapNotify, (XPointer) win);
  417.  
  418.     glXMakeCurrent(dpy, win, ctx);
  419.  
  420.     indexScale = (1 << vis->depth) - 1;
  421.     init();
  422.  
  423.     while (!done) {
  424.     do {
  425.         XNextEvent(dpy, &ev);
  426.         switch (ev.type) {
  427.           case KeyPress:
  428.         {
  429.             KeySym ks;
  430.             float p;
  431.  
  432.             XLookupString(&ev.xkey, NULL, 0, &ks, NULL);
  433.             switch (ks) {
  434.               case XK_Escape:
  435.             done = 1;
  436.             break;
  437.               case XK_O: case XK_o:
  438.             whichObject = (whichObject + 1) % NUM_OBJECTS;
  439.             break;
  440.               case XK_L: case XK_l:
  441.             useLighting = !useLighting;
  442.             break;
  443.               case XK_T: case XK_t:
  444.             useTwoSide = !useTwoSide;
  445.             break;
  446.               case XK_K: case XK_k:
  447.             useLocalLight = !useLocalLight;
  448.             break;
  449.               case XK_V: case XK_v:
  450.             useLocalViewer = !useLocalViewer;
  451.             break;
  452.               case XK_P: case XK_p:
  453.             useSpot = !useSpot;
  454.             break;
  455.               case XK_N: case XK_n:
  456.             useAtten = !useAtten;
  457.             break;
  458.               case XK_A:
  459.             p = matIndexRange[0] + 0.005;
  460.             if (p < 0.0) p = 0.0;
  461.             if (p > 1.0) p = 1.0;
  462.             matIndexRange[0] = p;
  463.             break;
  464.               case XK_a:
  465.             p = matIndexRange[0] - 0.005;
  466.             if (p < 0.0) p = 0.0;
  467.             if (p > 1.0) p = 1.0;
  468.             matIndexRange[0] = p;
  469.             break;
  470.               case XK_D:
  471.             p = matIndexRange[1] + 0.005;
  472.             if (p < 0.0) p = 0.0;
  473.             if (p > 1.0) p = 1.0;
  474.             matIndexRange[1] = p;
  475.             break;
  476.               case XK_d:
  477.             p = matIndexRange[1] - 0.005;
  478.             if (p < 0.0) p = 0.0;
  479.             if (p > 1.0) p = 1.0;
  480.             matIndexRange[1] = p;
  481.             break;
  482.               case XK_S:
  483.             p = matIndexRange[2] + 0.005;
  484.             if (p < 0.0) p = 0.0;
  485.             if (p > 1.0) p = 1.0;
  486.             matIndexRange[2] = p;
  487.             break;
  488.               case XK_s:
  489.             p = matIndexRange[2] - 0.005;
  490.             if (p < 0.0) p = 0.0;
  491.             if (p > 1.0) p = 1.0;
  492.             matIndexRange[2] = p;
  493.             break;
  494.               default:
  495.             break;
  496.             }
  497.         }
  498.         needsReconfig = 1;
  499.         needsRedraw = 1;
  500.         break;
  501.           case ButtonPress:
  502.         x0 = ev.xbutton.x;
  503.         y0 = ev.xbutton.y;
  504.         break;
  505.           case MotionNotify:
  506.         yrot += (float)(ev.xmotion.x-x0) * (360.0 / (float) width);
  507.         if (yrot > 360) yrot = yrot - 360;
  508.         if (yrot < 0) yrot = 360 - yrot;
  509.  
  510.         xrot += (float)(ev.xmotion.y-y0) * (360.0 / (float) height);
  511.         if (xrot > 360) xrot = xrot - 360;
  512.         if (xrot < 0) xrot = 360 - xrot;
  513.  
  514.         x0 = ev.xmotion.x; y0 = ev.xmotion.y;
  515.         needsRedraw = 1;
  516.         break;
  517.           case ConfigureNotify:
  518.         width = (unsigned int) ev.xconfigure.width;
  519.         height = (unsigned int) ev.xconfigure.height;
  520.         needsReconfig = 1;
  521.         needsRedraw = 1;
  522.         break;
  523.           case Expose:
  524.           default:
  525.         needsRedraw = 1;
  526.         break;
  527.         }
  528.     } while (XPending(dpy));
  529.  
  530.     if (needsReconfig) {
  531.         glViewport(0, 0, (float) width, (float) height);
  532.         reconfig();
  533.         needsReconfig = 0;
  534.     }
  535.  
  536.     if (needsRedraw) {
  537.         redraw(xrot, yrot);
  538.         glXSwapBuffers(dpy, win);
  539.         needsRedraw = 0;
  540.     }
  541.     }
  542. }
  543.